大家應該都看過名偵探柯南吧,那個智慧過於常人的小學生,東京死神,專長是踢足球跟在夏威夷學開飛機,興趣是用手錶把叔叔的脖子射得坑坑洞洞。
沒錯,我們的苦主毛利小五郎心理苦,但叔叔不說──我們今天要介紹的是 Sleeping 這個模組,被設定成 Sleeping 的物體,就像小五郎叔叔一樣,動也不動,直到被解除 Sleeping 的狀態為止。
開始看 Sleeping 這個模組前我們要先複習一下 body 上的兩個屬性:isSleeping 跟 sleepThreshold
//in default
sleepThreshold : 60
isSleeping : false
isSleeping 就是物體的初始狀態是否為 sleeping。
因為我們的 render option 有設定 showSleeping,如果是 sleeping 狀態的物體,會以稍暗的方式顯示。
sleepThreshold 則是在筆者撰寫文章的當下,又好好地看了一次,發現當初 Day8 的時候誤解他為速度的閥值,但其實不是(筆者寫這篇文章的時候已經改掉 Day8 的內容成正確的了)。
這個值要生效有一個前提條件是 engine 的 enableSleeping 要是 true。
var engine = Engine.create(options={
enableSleeping : true
});
enableSleeping這個數值是用來做什麼的呢?
本來我對 sleeping 的作用也是有些困惑,搜尋後有看到 matter.js 的作者有回答一個提出的 issue。
發問者好奇 sleeping 這個模組或是狀態當初設計的作用是什麼呢?作者回答,主要是用於讓一些完成碰撞檢測的物體進入 sleeping 狀態,可以帶來效能提升、減少 sleeping 物體的碰撞判斷,而當非 sleeping 物體與 sleeping 物體發生碰撞,則 sleeping 物體會被喚醒,進行運動。
整篇回答的重點在最後一句。
作者什麼都做好啦!只要你把 engine 的 enableSleeping 設成 true 允許 engine 透過 sleeping 模組來控制物體的 sleeping 狀態,他就會按邏輯來控制 sleeping 狀態,減小碰撞計算所花的效能,如堆疊在一起的靜止方盒,全部的方盒在沒有外力的情況下就都會是 sleeping 的狀態。
sleepThreshold 是建立在上面這個設定被設成 enable 的前提之下,規範當物體的在幾次udpate皆速度趨近於零則改變他的 sleeping 狀態,數字越小則越快進入 sleeping 的狀態,預設為 60。
雖然作者說交給 engine 自己處理就好,我們還是來看一下 sleeping 的方法們,總共有三個方法
第一個把 pair 當作傳入參數,很明顯主要是讓本來函式庫邏輯使用,這個我們就不深究。
第二個 update 方法可以看看原始碼,這邊可以看到上面提到的 sleepThreshold 被拿來檢測的痕跡,呼叫時機也是交由函式庫處理就好。
最後一個 set 是可以拿來試試的 function,使用上也很單純,就是傳入物體與要設置的狀態。
Sleeping 的狀態一旦物體本身仍有外力作用殘存,就會被喚醒, 如範例中的方塊撞到球,即使按下 trigger 球改變 sleeping 狀態的按鈕,球仍不會馬上進入 sleeping,必須等動能處理完。
如果 engine 的 enableSleeping 設成 false,則 engine 不會調動 Sleeping 模組來更新物體的 Sleeping 狀態,讀者可以試試這個改動(按一下 "Remove enableSleeping from engine" 按鈕再開始 runner ),方形落下後不會變成 Sleeping,碰到球體球體也不為所動。
其實這篇文章的重點就是在上面那個作者回答的最後一句,如果想增加碰撞判斷的效能,把 engine 中的 enableSleeping 設成 true就好啦!